package com.ncs.cns.framework.chat;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

import com.ncs.cns.business.to.OldMessage;
import com.ncs.cns.business.util.JsonConvertor;

public class OldChattingClient {
	private SocketChannel socketChannel =null;
	private ByteBuffer sendBuff = ByteBuffer.allocate(1024*2);
	private ByteBuffer receieveBuff = ByteBuffer.allocate(1024*5);
	private Charset charset = Charset.forName("UTF-8");
	private Selector selector ;
	
	public OldChattingClient() throws IOException{
		socketChannel = SocketChannel.open();
		InetAddress ia = InetAddress.getByName("Kenneth.wicp.net");
		InetSocketAddress isa = new InetSocketAddress(ia,11713);
//		InetAddress ia = InetAddress.getByName("192.168.199.101");
//		InetSocketAddress isa = new InetSocketAddress(ia,8000);
		socketChannel.connect(isa);		
		socketChannel.configureBlocking(false);
		System.out.println("Connecting to Server Successfully ......");
		selector = Selector.open();	
	}
	
	
	public ByteBuffer encode(String str){
		return charset.encode(str);
	}
	
	public String decode(ByteBuffer buffer){
		CharBuffer charBuffer = charset.decode(buffer);
		return charBuffer.toString();
	}
	
	
	public void receieveFromUser(OldMessage message) throws IOException{
		//BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
		//String keyIn = null;
		//while((keyIn=localReader.readLine())!=null){
		//message.setContent(keyIn);
		String msg = JsonConvertor.getInstance().conver2JsonStr(message);
		synchronized(sendBuff){
			sendBuff.put(encode(msg+"\r\n"));
		}
		if(msg.equals("bye")){
			return;
		}
		//}
	}
	
	public void talk() throws IOException {
		while(!selector.isOpen()){
			selector.open();
		}
		socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
		while(selector.select()>0){
			try {
				Thread.currentThread().sleep(500);
			} catch (InterruptedException e2) {
				e2.printStackTrace();
			}
			Set readyKeys = selector.selectedKeys();
			Iterator it = readyKeys.iterator();
			while(it.hasNext()){
				SelectionKey key = null ;
				try {
					key=(SelectionKey)it.next();
					it.remove();
					if(key.isReadable()){receieve(key);}
					if(key.isWritable()){send(key);}
				} catch (Exception e) {
					e.printStackTrace();
					try {
						if(key!=null){
							key.cancel();
							key.channel().close();
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
			}			
		}
	}
	
	public void closeConnection(){
		if(socketChannel.isOpen()){
			try {
				socketChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
//			try {
//				if(selector.select() > 0){
//					Set readyKeys = selector.selectedKeys();
//					Iterator it = readyKeys.iterator();
//					while(it.hasNext()){
//						SelectionKey key = null ;
//						try {
//							key=(SelectionKey)it.next();
//							it.remove();
//						} catch (Exception e) {
//							e.printStackTrace();							
//						}
//						try {
//							if(key!=null){
//								key.cancel();
//								key.channel().close();
//							}
//						} catch (Exception e1) {
//							e1.printStackTrace();
//						}
//					}
//				}
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
		}
	}
	
	public void receieve (SelectionKey key) throws IOException{
		SocketChannel channel = (SocketChannel)key.channel();
		channel.read(receieveBuff);
		receieveBuff.flip();
		String receieveData=decode(receieveBuff);
		if(receieveData.indexOf("\n")==-1)return;
		String output = receieveData.substring(0,receieveData.indexOf("\n")+1);
		System.out.println(output);
		if(output.equals("echo:bye\r\n")){
			key.cancel();
			socketChannel.close();
			System.out.println("Closing connection to server ......");
			selector.close();
			System.exit(0);
		}		
		updateUI(output);
		ByteBuffer temp = encode(output);
		receieveBuff.position(temp.limit());
		receieveBuff.compact();
	}
	
	

	public void send(SelectionKey key) throws IOException{
		SocketChannel socketChannel = (SocketChannel)key.channel();
		synchronized (sendBuff){
			sendBuff.flip();
			socketChannel.write(sendBuff);
			sendBuff.compact();	
		}
	}
	
	protected void updateUI(String output) {
		
	}
	
	
//	/**
//	 * @param args
//	 * @throws IOException 
//	 */
//	public static void main(String[] args) throws IOException {
//		// TODO Auto-generated method stub
//		final ChattingClient client = new ChattingClient();
//		Thread receiever = new Thread(){
//			public void run(){
//				try {
//					client.receieveFromUser();
//				} catch (IOException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//			}
//		};
//		receiever.start();
//		client.talk();
//	}

}
